package com.live.shop.aliyun;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.text.format.DateFormat;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Locale;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.live.shop.model.UserModel;
import com.live.shop.sql.UserDatabase;
import com.live.shop.tool.GetUtil;
import com.live.shop.tool.TtsMessageEvent;

import org.greenrobot.eventbus.EventBus;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class AliyunTtsUtil {
    private final String appkey;
    private final String accessKeyID;
    private final String accessKeySecret;
    public AliyunTtsUtil(String appkey, String accessKeyID, String accessKeySecret) {
        this.appkey = appkey;
        this.accessKeyID = accessKeyID;
        this.accessKeySecret = accessKeySecret;
    }

    //语音合成API
    public void postRequest(Context context,String text, String audioSaveFile) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
                UserDatabase userDb = new UserDatabase(context);
                UserModel userModel = userDb.select();
                String token = null;
                if(userModel.getAliyunToken() != null && !userModel.getAliyunToken().isEmpty() && userModel.getAliyunExpiredTime() > System.currentTimeMillis() / 1000){
                    //Token不为空 且 未到期
                    token = userModel.getAliyunToken();
                }else{
                    //Token 已到期
                    JSONObject tokenJson = AliyunToken.getTokenRequest(accessKeyID, accessKeySecret);
                    if(tokenJson.getIntValue("code") == 0){
                        EventBus.getDefault().post(new TtsMessageEvent(3,tokenJson.getString("error")));
                        return;
                    }else{
                        UserModel tokenModel = new UserModel();
                        tokenModel.setAliyunToken(tokenJson.getString("token"));
                        tokenModel.setAliyunExpiredTime(tokenJson.getLong("expireTime"));
                        userDb.updateAliToken(tokenModel);
                        token = tokenJson.getString("token");
                    }
                }

                String font_name = userModel.getAliyunFontName();
                String speed_level = userModel.getAliyunSpeedLevel();
                String volume = userModel.getAliyunVolume();

                JSONObject taskObject = new JSONObject();
                taskObject.put("appkey", appkey);
                taskObject.put("token", token);
                taskObject.put("text", text);
                taskObject.put("format", "MP3");//音频编码格式，支持PCM/WAV/MP3格式。
                taskObject.put("voice", font_name);// 在线语音合成发音人
                taskObject.put("sample_rate","16000");//音频采样率，默认值：16000 Hz，
                taskObject.put("volume", Integer.valueOf(volume));// volume 音量，Integer 范围是0~100，可选，默认50。【语调，取值范围：0～2，默认值：1.0。】
                taskObject.put("speech_rate", Integer.valueOf(speed_level));//语速，Integer 取值范围：-500~500，默认值：0。【原来 值范围：0～2，默认值：1.0】
                taskObject.put("pitch_rate", 0);// pitch_rate 语调，Integer 范围是-500~500，可选，默认是0。
                String bodyContent = taskObject.toJSONString();

                RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
                Request request = new Request.Builder()
                        .url(url)
                        .header("Content-Type", "application/json")
                        .post(reqBody)
                        .build();
                try {
                    OkHttpClient client = new OkHttpClient();
                    Response response = client.newCall(request).execute();
                    String contentType = response.header("Content-Type");
                    if ("audio/mpeg".equals(contentType)) {
                        File f = new File(audioSaveFile);
                        FileOutputStream fout = new FileOutputStream(f);
                        fout.write(response.body().bytes());
                        fout.close();
                        //生成完毕
                        EventBus.getDefault().post(new TtsMessageEvent(1,"合成完毕.",audioSaveFile));
                    }else {
                        //请求失败
                        String errorMessage = response.body().string();
                        JSONObject errorObj = JSON.parseObject(errorMessage);
                        switch (errorObj.getInteger("status")){
                            case 40000000:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：默认的客户端错误码。请检查对应的错误消息。"));break;
                            case 40000001:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：身份认证失败。请检查使用的令牌是否正确，是否过期。"));break;
                            case 40000002:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：无效的消息。请检查发送的消息是否符合要求。"));break;
                            case 40000003:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：无效的参数。请检查参数值设置是否合理。"));break;
                            case 40000004:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：空闲超时。请确认是否长时间没有发送数据到服务端。"));break;
                            case 40000005:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：请求数量过多。请检查是否超过了并发连接数或者每秒钟请求数。"));break;
                            case 40000010:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：试用期已结束，并且未开通商用版、或账户欠费。请登录控制台确认服务开通状态以及账户余额。"));break;
                            default:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]："+errorMessage));break;
                        }
                    }
                    response.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //语音合成API
    public void postRequestPlayAudio(Context context,String text,String font_name,String speed_level,String volume) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = "https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts";
                String audioSaveFile = context.getCacheDir().getPath()+ DateFormat.format("yyyyMMdd_HHmmss", Calendar.getInstance(Locale.CHINA)) + ".mp3";
                UserDatabase userDb = new UserDatabase(context);
                UserModel userModel = userDb.select();

                String token = null;
                if(userModel.getAliyunToken() != null && !userModel.getAliyunToken().isEmpty() && userModel.getAliyunExpiredTime() > System.currentTimeMillis() / 1000){
                    //Token不为空 且 未到期
                    token = userModel.getAliyunToken();
                }else{
                    //Token 已到期
                    JSONObject tokenJson = AliyunToken.getTokenRequest(accessKeyID, accessKeySecret);
                    if(tokenJson.getIntValue("code") == 0){
                        EventBus.getDefault().post(new TtsMessageEvent(3,tokenJson.getString("error")));
                        return;
                    }else{
                        UserModel tokenModel = new UserModel();
                        tokenModel.setAliyunToken(tokenJson.getString("token"));
                        tokenModel.setAliyunExpiredTime(tokenJson.getLong("expireTime"));
                        userDb.updateAliToken(tokenModel);
                        token = tokenJson.getString("token");
                    }
                }
                Log.d(GetUtil.TAG,"[appkey]"+appkey);
                JSONObject taskObject = new JSONObject();
                taskObject.put("appkey", appkey);
                taskObject.put("token", token);
                taskObject.put("text", text);
                taskObject.put("format", "MP3");//音频编码格式，支持PCM/WAV/MP3格式。
                taskObject.put("voice", font_name);// 在线语音合成发音人
                taskObject.put("sample_rate","16000");//音频采样率，默认值：16000 Hz，
                taskObject.put("volume", Integer.valueOf(volume));// volume 音量，Integer 范围是0~100，可选，默认50。【语调，取值范围：0～2，默认值：1.0。】
                taskObject.put("speech_rate", Integer.valueOf(speed_level));//语速，Integer 取值范围：-500~500，默认值：0。【原来 值范围：0～2，默认值：1.0】
                taskObject.put("pitch_rate", 0);// pitch_rate 语调，Integer 范围是-500~500，可选，默认是0。
                String bodyContent = taskObject.toJSONString();

                RequestBody reqBody = RequestBody.create(MediaType.parse("application/json"), bodyContent);
                Request request = new Request.Builder()
                        .url(url)
                        .header("Content-Type", "application/json")
                        .post(reqBody)
                        .build();
                try {
                    OkHttpClient client = new OkHttpClient();
                    Response response = client.newCall(request).execute();
                    String contentType = response.header("Content-Type");
                    if ("audio/mpeg".equals(contentType)) {
                        File f = new File(audioSaveFile);
                        FileOutputStream fout = new FileOutputStream(f);
                        fout.write(response.body().bytes());
                        fout.close();

                        EventBus.getDefault().post(new TtsMessageEvent(3,"合成完毕，播放中.."));
                        //生成完毕
                        MediaPlayer mediaPlayer = new MediaPlayer();
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                        mediaPlayer.setDataSource(context, Uri.parse(audioSaveFile));
                        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                            @Override
                            public void onCompletion(MediaPlayer mediaPlayer) {
                                mediaPlayer.release();
                                File file = new File(audioSaveFile);
                                if (file.exists()) {
                                    file.delete();
                                }
                            }
                        });
                        mediaPlayer.prepare();
                        mediaPlayer.start();
                    }
                    else {
                        //请求失败
                        String errorMessage = response.body().string();
                        Log.d(GetUtil.TAG,"[合成失败]"+errorMessage);
                        JSONObject errorObj = JSON.parseObject(errorMessage);
                        switch (errorObj.getInteger("status")){
                            case 40000000:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：默认的客户端错误码。请检查对应的错误消息。"));break;
                            case 40000001:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：身份认证失败。请检查使用的令牌是否正确，是否过期。"));break;
                            case 40000002:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：无效的消息。请检查发送的消息是否符合要求。"));break;
                            case 40000003:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：无效的参数。请检查参数值设置是否合理。"));break;
                            case 40000004:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：空闲超时。请确认是否长时间没有发送数据到服务端。"));break;
                            case 40000005:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：请求数量过多。请检查是否超过了并发连接数或者每秒钟请求数。"));break;
                            case 40000010:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]：试用期已结束，并且未开通商用版、或账户欠费。请登录控制台确认服务开通状态以及账户余额。"));break;
                            default:EventBus.getDefault().post(new TtsMessageEvent(3,"[语音合成失败]："+errorMessage));break;
                        }
                    }
                    response.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
